/**
 * 鼠标悬浮高亮组件
 * 使用 Canvas 绘制整行整列的高亮边框
 */

import { useEffect, useRef } from 'react'
import type { PluginComponentProps } from '../../types'
import './styles.css'

interface HoverState {
  row: number
  col: number
  x: number
  y: number
}

interface ScrollState {
  scrollX: number
  scrollY: number
}

export function HoverHighlight({ context }: PluginComponentProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const hoverStateRef = useRef<HoverState | null>(null)
  const animationFrameRef = useRef<number>()
  const scrollStateRef = useRef<ScrollState>({ scrollX: 0, scrollY: 0 })
  const containerRef = useRef<HTMLDivElement | null>(null)

  useEffect(() => {
    // 监听滚动事件，同步滚动位置
    const handleCanvasScroll = (data: { scrollX: number; scrollY: number }) => {
      scrollStateRef.current = {
        scrollX: data.scrollX,
        scrollY: data.scrollY,
      }

      // 如果当前有悬浮状态，重新绘制高亮（清除残留）
      if (canvasRef.current && hoverStateRef.current) {
        const canvas = canvasRef.current
        const ctx = canvas.getContext('2d')
        if (!ctx) return

        const config = {
          headerHeight: 60,
          departmentColumnWidth: 120,
          employeeColumnWidth: 120,
          cellWidth: 120,
          cellHeight: 60,
          highlightColor: '#000000',
          highlightWidth: 3,
        }

        // 完全清除整个 Canvas
        const width = canvas.width / (window.devicePixelRatio || 1)
        const height = canvas.height / (window.devicePixelRatio || 1)
        ctx.clearRect(0, 0, width, height)

        const { row, col } = hoverStateRef.current
        const {
          headerHeight,
          departmentColumnWidth,
          employeeColumnWidth,
          cellWidth,
          cellHeight,
          highlightColor,
          highlightWidth,
        } = config
        const fixedColumnsWidth = departmentColumnWidth + employeeColumnWidth
        const { scrollX, scrollY } = scrollStateRef.current

        ctx.strokeStyle = highlightColor
        ctx.lineWidth = highlightWidth

        const employees = context.getEmployees()

        // 计算实际单元格位置（考虑滚动）
        const cellX = fixedColumnsWidth + col * cellWidth - scrollX
        const cellY = headerHeight + row * cellHeight - scrollY

        // 绘制整行高亮（从员工列开始，横跨整个可视区域）
        if (row >= 0 && row < employees.length) {
          const rowY = cellY
          // 检查是否在可见区域
          if (rowY + cellHeight > headerHeight && rowY < height) {
            // 从员工列开始（不包括部门列），一直延伸到右边界
            ctx.strokeRect(
              departmentColumnWidth, // 从员工列开始
              rowY + highlightWidth / 2, // 居中线条
              width - departmentColumnWidth, // 延伸到容器最右侧
              cellHeight - highlightWidth
            )
          }
        }

        // 绘制整列高亮（从表头开始，竖跨整个可视区域）
        if (col >= 0) {
          const colX = cellX
          // 检查是否在可见区域
          if (colX + cellWidth > fixedColumnsWidth && colX < width) {
            // 从顶部固定表头开始，一直延伸到底部边界
            ctx.strokeRect(
              colX + highlightWidth / 2, // 居中线条
              0, // 从容器最顶部开始
              cellWidth - highlightWidth,
              height // 延伸到容器最底部
            )
          }
        }
      }
    }

    context.on('canvas:scroll', handleCanvasScroll)

    const timer = setTimeout(() => {
      const containers = document.querySelectorAll('.canvas-renderer-container')
      const targetContainer = containers[0] as HTMLDivElement | null

      if (!targetContainer) {
        console.warn('⚠️ HoverHighlight: 未找到 canvas-renderer-container')
        return
      }

      containerRef.current = targetContainer

      const canvas = canvasRef.current
      if (!canvas) return

      const ctx = canvas.getContext('2d')
      if (!ctx) return

      canvas.style.display = 'block'
      targetContainer.appendChild(canvas)

      console.log('✅ HoverHighlight: Canvas 已添加到容器', {
        canvasSize: { width: canvas.width, height: canvas.height },
        container: targetContainer.className,
      })

      const config = {
        headerHeight: 60,
        departmentColumnWidth: 120,
        employeeColumnWidth: 120,
        cellWidth: 120,
        cellHeight: 60,
        highlightColor: '#000000',
        highlightWidth: 3,
      }

      const resizeCanvas = () => {
        const rect = targetContainer.getBoundingClientRect()
        const dpr = window.devicePixelRatio || 1

        canvas.width = rect.width * dpr
        canvas.height = rect.height * dpr
        canvas.style.width = `${rect.width}px`
        canvas.style.height = `${rect.height}px`

        ctx.scale(dpr, dpr)
      }

      resizeCanvas()
      window.addEventListener('resize', resizeCanvas)

      const drawHighlight = () => {
        // 完全清除整个 Canvas
        const width = canvas.width / (window.devicePixelRatio || 1)
        const height = canvas.height / (window.devicePixelRatio || 1)
        ctx.clearRect(0, 0, width, height)

        if (!hoverStateRef.current) return

        const { row, col } = hoverStateRef.current
        const {
          headerHeight,
          departmentColumnWidth,
          employeeColumnWidth,
          cellWidth,
          cellHeight,
          highlightColor,
          highlightWidth,
        } = config
        const fixedColumnsWidth = departmentColumnWidth + employeeColumnWidth
        const { scrollX, scrollY } = scrollStateRef.current

        ctx.strokeStyle = highlightColor
        ctx.lineWidth = highlightWidth

        const employees = context.getEmployees()

        // 计算实际单元格位置（考虑滚动）
        const cellX = fixedColumnsWidth + col * cellWidth - scrollX
        const cellY = headerHeight + row * cellHeight - scrollY

        // 绘制整行高亮（从员工列开始，横跨整个可视区域）
        if (row >= 0 && row < employees.length) {
          const rowY = cellY
          // 检查是否在可见区域
          if (rowY + cellHeight > headerHeight && rowY < height) {
            // 从员工列开始（不包括部门列），一直延伸到右边界
            ctx.strokeRect(
              departmentColumnWidth, // 从员工列开始
              rowY + highlightWidth / 2, // 居中线条
              width - departmentColumnWidth, // 延伸到容器最右侧
              cellHeight - highlightWidth
            )
          }
        }

        // 绘制整列高亮（从表头开始，竖跨整个可视区域）
        if (col >= 0) {
          const colX = cellX
          // 检查是否在可见区域
          if (colX + cellWidth > fixedColumnsWidth && colX < width) {
            // 从顶部固定表头开始，一直延伸到底部边界
            ctx.strokeRect(
              colX + highlightWidth / 2, // 居中线条
              0, // 从容器最顶部开始
              cellWidth - highlightWidth,
              height // 延伸到容器最底部
            )
          }
        }
      }

      const handleMouseMove = (event: MouseEvent) => {
        // 使用容器的坐标，因为 Canvas 和容器大小一致
        const rect = targetContainer.getBoundingClientRect()
        const x = event.clientX - rect.left
        const y = event.clientY - rect.top

        const { headerHeight, departmentColumnWidth, employeeColumnWidth, cellWidth, cellHeight } =
          config
        const fixedColumnsWidth = departmentColumnWidth + employeeColumnWidth
        const { scrollX, scrollY } = scrollStateRef.current

        let row = -1
        let col = -1

        if (x >= fixedColumnsWidth && y >= headerHeight) {
          // 计算时需要加上滚动偏移
          col = Math.floor((x - fixedColumnsWidth + scrollX) / cellWidth)
          row = Math.floor((y - headerHeight + scrollY) / cellHeight)

          const employees = context.getEmployees()
          if (row >= employees.length) row = -1
          if (col >= 31) col = -1
        }

        const prevState = hoverStateRef.current
        const hasChanged = !prevState || prevState.row !== row || prevState.col !== col

        if (hasChanged) {
          hoverStateRef.current = row >= 0 && col >= 0 ? { row, col, x, y } : null

          if (animationFrameRef.current) {
            cancelAnimationFrame(animationFrameRef.current)
          }

          animationFrameRef.current = requestAnimationFrame(drawHighlight)
        }
      }

      const handleMouseLeave = () => {
        hoverStateRef.current = null
        if (animationFrameRef.current) {
          cancelAnimationFrame(animationFrameRef.current)
        }
        ctx.clearRect(0, 0, canvas.width, canvas.height)
      }

      // 监听容器而非 Canvas 的鼠标事件（因为 Canvas 设置了 pointer-events: none）
      targetContainer.addEventListener('mousemove', handleMouseMove)
      targetContainer.addEventListener('mouseleave', handleMouseLeave)

      return () => {
        window.removeEventListener('resize', resizeCanvas)
        targetContainer.removeEventListener('mousemove', handleMouseMove)
        targetContainer.removeEventListener('mouseleave', handleMouseLeave)
        if (animationFrameRef.current) {
          cancelAnimationFrame(animationFrameRef.current)
        }
        if (canvas.parentElement) {
          canvas.parentElement.removeChild(canvas)
        }
      }
    }, 100)

    return () => {
      clearTimeout(timer)
      context.off('canvas:scroll', handleCanvasScroll)
    }
  }, [context])

  return <canvas ref={canvasRef} className="hover-highlight-canvas" style={{ display: 'none' }} />
}
